import struct
from none_bot_py_plugins.net import mod_msg
from none_bot_py_plugins.net import socket_main
import asyncio
#
#
# s = s2c_test()
# s.id = 15
# s.data = "456123"
#
# s1 = s.SerializeToString()
# l = len(s1)
#
# msg_id = 1001
#
# bin = struct.pack("!HH"+str(l)+"s", l, msg_id, s1)
#
# print("msg_id :", msg_id)
# print("id:", s.id)
# print("data:", s.data)
# print("send bin:", bin)
# print("bin len:", len(s1))
# ADDR = ("localhost", 9088)
#
# tcpCliSock = socket(AF_INET, SOCK_STREAM)
# tcpCliSock.connect(ADDR)
# tcpCliSock.send(bin)
#
# print("send finish")


class NetHolder(asyncio.Protocol):
    __uuid = 0
    __socket = None
    __port = None
    __local_address = None
    transport = None

    def start_link(self):
        self.__socket = None

    def pack_send(self, proto_object):
        if self.__socket is not None:
            if hasattr(proto_object, 'SerializeToString'):
                try:
                    object_bin = proto_object.SerializeToString()
                    class_name = class_full_name(proto_object)
                    msg_id = mod_msg.c2s_mod2msg[class_name]
                    l_info = len(object_bin)
                    bin_data = struct.pack("!HH"+str(l_info)+"s", l_info, msg_id, object_bin)
                    self.transport.write(bin_data)
                except:
                    print("proto_object err:", class_full_name(proto_object))
                    raise
            else:
                print("no attr ", proto_object)
        else:
            print("no socket:", self.__socket)

    def __init__(self, uuid):
        self.__uuid = uuid
        print(self.__uuid, ": NetHolder init")

    def connection_made(self, transport: asyncio.Transport) -> None:
        self.transport = transport
        self.__socket = transport.get_extra_info('socket')
        self.__local_address, self.__port = self.__socket.getsockname()
        print("建立连接：", self.__local_address, self.__port)

    def data_received(self, data: bytes) -> None:
        data_len = len(data)
        _msg_len, msg_id, msg = struct.unpack("!HH"+str(data_len - 4)+"s", data)
        full_name = mod_msg.s2c_msg2mod[msg_id]
        split_list = full_name.split(".")
        mod_name = split_list[0]
        class_name = split_list[1]
        proto_object = getattr(globals()[mod_name], class_name)()
        proto_object.ParseFromString(msg)

        socket_main.recv_info(self.__uuid, proto_object)

    def connection_lost(self, exc):
        print('服务器连接断开：', self.__uuid)
        socket_main.stop(self.__uuid)


def class_full_name(obj):
    return obj.__class__.__module__+"." + obj.__class__.__name__
